import mysql = require("mysql")
import { Logger } from "./Logger";

export class MysqlClient {

    public host: string; //数据库地址
    public port: number;
    public user: string;
    public pass: string;
    public database: string;

    private pool;

    public static async create(database: string, host: string, port: number, user: string, pass: string) {
        let mysqlClient: MysqlClient = new MysqlClient();
        mysqlClient.database = database;
        mysqlClient.host = host;
        mysqlClient.port = port;
        mysqlClient.user = user;
        mysqlClient.pass = pass;
        mysqlClient.pool = mysql.createPool({
            connectionLimit: 10,
            host: mysqlClient.host,
            port: mysqlClient.port,
            user: mysqlClient.user,
            password: mysqlClient.pass,
            database: mysqlClient.database
        });
        Logger.info("MysqlClient.init", database, host, port, user, pass)
        mysqlClient.init()
        return mysqlClient
    }

    public init() {
        this.pool.on('release', (connection) => {
            // Logger.log('MysqlClient released', this.database, connection.threadId);
        });
        return new Promise((resolve, reject) => {
            this.pool.on('connection', (connection) => {
                // Logger.log("MysqlClient.connection=", this.database, connection)
                resolve(null);
            });
        })

    }

    public test() {
        Logger.log("test")
        // this.select("SELECT * FROM users;", () => {

        // })
    }

    public queryPromise(sql: string, sqlParams: Array<any> = null): Promise<any> {
        return new Promise((resolve, reject) => {
            this.query(sql, sqlParams, (err, results, fields) => {
                resolve(results)
            })
        })
    }

    public query(sql: string, sqlParams: Array<any> = null, callback: Function = null) {
        this.pool.getConnection((err, connection) => {
            if (err) {
                Logger.error("query error", err)
                callback && callback(err, [], [])
                return;
            }
            // Use the connection
            connection.query(sql, sqlParams, (error, results, fields) => {
                // When done with the connection, release it.
                connection.release();
                // Handle error after the release.
                if (error) {
                    Logger.error("query error=", sql, sqlParams, this.database, error)
                    callback && callback(error, [], [])
                    return;
                }
                // Don't use the connection here, it has been returned to the pool.
                // Logger.log("result", results)
                // Logger.log("fields", fields)
                callback && callback(err, results, fields)
            });
        });
    }

    public destroy() {
        Logger.info("MysqlClient.destroy", this.database)
        this.pool.end((err) => {
            Logger.info("MysqlClient.end=", err)
            this.pool.removeAllListeners()
            this.pool = null;
        })
    }
}